<template>
  <div class="app-container wh100">
    <el-row :gutter="20" class="wh100">
      <el-col :span="4" :xs="24">
        <el-input v-model="filterText" placeholder="输入名称搜索" clearable />
        <el-tree
          ref="tree"
          v-loading="loadingTree"
          class="mt5"
          empty-text="无数据"
          :data="tree"
          :filter-node-method="filterNode"
          :expand-on-click-node="false"
          highlight-current
          node-key="orgId"
          :default-expanded-keys="[1,-10,-11]"
          :current-node-key="orgId"
          :props="defaultProps"
          @node-click="handleNodeClick"
        >
          <span slot-scope="{ node, data }" class="custom-tree-node">
            <span>
              <i :class="data.iconClass" />{{ data.orgName }}
            </span>
          </span>
        </el-tree>
      </el-col>
      <el-col :span="20" :xs="24">
        <el-container>
          <el-header class="w-header left solid-bottom">
            <el-button
              size="small"
              type="primary"
              plain
              :loading="savingRight"
              icon="iconfont icon-baocunwendang mr5"
              :disabled="!canSaveR"
              @click="saveRight"
            >保 存</el-button>
            <el-button
              size="small"
              type="danger"
              plain
              :loading="clearSelf"
              icon="el-icon-circle-close"
              class="ml5"
              :disabled="orgId<=0"
              @click="clearSelfRight"
            >清空权限</el-button>
            <el-button
              type="primary"
              plain
              icon="el-icon-sort"
              size="mini"
              @click="toggleExpandAll"
            >展开/折叠</el-button>
            <el-input v-model="filterMenu" placeholder="输入名称搜索" clearable class="w250 ml10" />
          </el-header>
          <el-main class="p0 pl10 pr10">
            <el-tree
              v-if="refreshTable"
              ref="menu"
              v-loading="loadingMenu"
              :data="right"
              class="mt5"
              empty-text="无数据"
              check-strictly
              show-checkbox
              :filter-node-method="filterMenuNode"
              highlight-current
              :default-expand-all="isExpandAll"
              :expand-on-click-node="false"
              check-on-click-node
              node-key="menuId"
              :default-expanded-keys="[]"
              :default-checked-keys="tempCheckKeys"
              :props="menuProps"
              @node-click="logMenu"
              @check="checkChange"
            >
              <span slot-scope="{ node, data }" class="custom-tree-node">
                <span :class="{'blue':data.self}">
                  <i :class="iconMap[data.menuType]+' mr5'" />{{ data.menuName }}
                </span>
              </span>
            </el-tree>
          </el-main>
        </el-container>
      </el-col>
    </el-row>
  </div>

</template>

<script>

import { clearSelfRight, rightData, saveTreeRight } from '@/api/right'
import { fullTree } from '@/api/org'
export default {
  name: 'MenuRight',
  data() {
    return {
      tree: [],
      right: [],
      iconMap: { 'M': 'mr5 el-icon-folder', 'C': 'mr5 el-icon-tickets', 'F': 'mr5 el-icon-link', 'B': 'mr5 el-icon-open' },
      checkKeys: [],
      tempCheckKeys: [],
      loadingTree: false,
      loadingMenu: false,
      clearSelf: false,
      savingRight: false,
      isExpandAll: true,
      refreshTable: true,
      orgId: 0,
      defaultProps: {
        children: 'childs',
        label: 'orgName'
      },
      menuProps: {
        children: 'children',
        label: 'menuName'
      },
      filterText: '',
      filterMenu: ''
    }
  },
  computed: {
    canSaveR() {
      return this.orgId > 1 && this.canSave()
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    filterMenu(val) {
      this.$refs.menu.filter(val)
    }
  },
  mounted() {
    this.initTree()
  },
  methods: {
    saveRight() {
      const par = this.getChangePar()
      this.savingRight = true
      saveTreeRight(par).then(() => {
        this.$message.success('保存成功')
        this.savingRight = false
        this.loadRightData(this.orgId)
      })
    },
    /** 展开/折叠操作 */
    toggleExpandAll() {
      this.refreshTable = false
      this.isExpandAll = !this.isExpandAll
      this.$nextTick(() => {
        this.refreshTable = true
      })
    },
    clearSelfRight() {
      this.$confirm('是否要清除自身权限？继承的权限不会受影响', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.clearSelf = true
        const par = { orgId: this.orgId, rightKey: 'MENU_RIGHT', rightType: 'YES' }
        clearSelfRight(par).then(() => {
          this.$message.success('操作成功')
          this.clearSelf = false
          this.loadRightData(this.orgId)
        })
      })
    },
    checkChange(node, b) {
      /* const arr = b.checkedKeys
      this.tempCheckKeys = arr */
      console.log('checkChange', node, b)
      this.hanleCheck(node, b)
      this.tempCheckKeys = this.$refs.menu.getCheckedKeys()
    },
    hanleCheck(data, node) {
      const _this = this
      // 获取当前节点是否被选中
      const isChecked = this.$refs.menu.getNode(data).checked
      // 如果当前节点被选中，则遍历上级节点和下级子节点并选中，如果当前节点取消选中，则遍历下级节点并取消选中
      if (isChecked) {
        // 判断是否有上级节点，如果有那么遍历设置上级节点选中
        data.parentId && setParentChecked(data.parentId)
        // 判断该节点是否有下级节点，如果有那么遍历设置下级节点为选中
        data.children && setChildrenChecked(data.children, true)
      } else {
        // 如果节点取消选中，则取消该节点下的子节点选中
        data.children && setChildrenChecked(data.children, false)
      }
      function setParentChecked(parentId) {
        // 获取该id的父级node
        const parentNode = _this.$refs.menu.getNode(parentId)
        // 如果该id的父级node存在父级id则继续遍历
        parentNode && parentNode.data && parentNode.data.parentId && setParentChecked(parentNode.data.parentId)
        //  设置该id的节点为选中状态
        _this.$refs.menu.setChecked(parentId, true)
      }
      function setChildrenChecked(node, isChecked) {
        node.forEach(item => {
          item.children && setChildrenChecked(item.children, isChecked)
          _this.$refs.menu.setChecked(item.menuId, isChecked)
        })
      }
    },
    canSave() {
      const l1 = this.checkKeys
      const l2 = this.tempCheckKeys
      if (l1.length !== l2.length) {
        return true
      } else {
        for (let i = 0; i < l1.length; i++) {
          if (l1[i] !== l2[i]) {
            return true
          }
        }
        return false
      }
    },
    getChangePar() {
      const l1 = this.checkKeys
      const l2 = this.tempCheckKeys
      // 取消勾选的
      const cancle = l1.filter(o => l2.indexOf(o) === -1)
      // 新增的
      const add = l2.filter(o => l1.indexOf(o) === -1)
      const par = { orgId: this.orgId, rightKey: 'MENU_RIGHT', rightType: 'YES' }
      const changeNode = []
      for (let i = 0; i < add.length; i++) {
        changeNode.push({ id: add[i], checked: true })
      }
      for (let i = 0; i < cancle.length; i++) {
        changeNode.push({ id: cancle[i], checked: false })
      }
      par.changeNode = changeNode
      return par
    },
    initTree() {
      this.loadingTree = true
      fullTree().then((res) => {
        const l = res.data
        this.tree = l
        this.loadingTree = false

        this.loadRightData(0)
      }).catch(() => {
        this.loadingTree = false
      })
    },
    loadRightData(orgId) {
      this.loadingMenu = true
      rightData({ orgId: orgId }).then((res) => {
        this.checkKeys = res.data.checkKeys
        this.tempCheckKeys = res.data.checkKeys
        this.right = res.data.right

        this.loadingMenu = false
        if (this.filterMenu) {
          this.$nextTick(() => {
            this.$refs.menu.filter(this.filterMenu)
          })
        }
      }).catch(() => {
        this.loadingMenu = false
      })
    },
    handleNodeClick(e) {
      if (e.orgId > 1) {
        this.orgId = e.orgId
        this.loadRightData(this.orgId)
      } else {
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(this.orgId)
        })
      }
    },
    logMenu(e) {
      console.log(e)
    },
    filterNode(value, data) {
      if (!value) return true
      return data.orgName.indexOf(value) !== -1
    },
    filterMenuNode(value, data) {
      if (!value) return true
      return data.menuName.indexOf(value) !== -1
    }
  }
}
</script>
<style scoped>

</style>
